﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq.Expressions;

namespace Neotic.DataAccess.Sql.Operations
{
    public abstract class ComparisonOperator : ISqlCondition
    {
        private ISelectColumn _leftColumn;
        private ISelectColumn _rightColumn;
        private object _value;

        public ComparisonOperator(ISelectColumn c, object val)
        {
            if (c == null)
                throw new ArgumentNullException("Paramètre c attendu");

            if (val == null)
                throw new ArgumentNullException("Paramètre val attendu");

            _leftColumn = c;
            _value = val;
        }

        public ComparisonOperator(ISelectColumn c1, ISelectColumn c2)
        {
            if (c1 == null)
                throw new ArgumentNullException("Paramètre c1 attendu");

            if (c2 == null)
                throw new ArgumentNullException("Paramètre c2 attendu");

            _leftColumn = c1;
            _rightColumn = c2;
        }

        public abstract string Operator { get; }

        public abstract ExpressionType? MyExpressionType { get; }

        public virtual string ToSql(DbParameterCollection cmdParams)
        {
            string rightPart = string.Empty;

            if (_rightColumn == null)
            {
                string pName = string.Concat("@P", cmdParams.Count);
                cmdParams.Add(new SqlParameter(pName, _value));
                rightPart = pName;
            }
            else
            {
                rightPart = _rightColumn.FullName;
            }

            return string.Concat(_leftColumn.FullName, " ", Operator, " ", rightPart);
        }

        public virtual ISqlCondition ParseExpression(Expression<Func<ISqlCondition, object>> predicate)
        {
            if (predicate.NodeType == this.MyExpressionType
                && predicate.Body is BinaryExpression)
            {
                BinaryExpression operation = (BinaryExpression)predicate.Body;

                ParameterExpression left = (ParameterExpression)operation.Left;
                ConstantExpression right = (ConstantExpression)operation.Right;
            }

            return null;
        }

    }
}
